package com.sample;

import java.time.LocalTime;
import java.util.Collection;
import java.util.List;
import java.util.UUID;

import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import com.sample.entity.Test;
import com.swak.App;
import com.swak.boot.Application;
import com.swak.utils.Fmt;
import com.swak.utils.Lists;

/**
 * Mybatis 测试
 * 
 * @author 618lf
 */
@SpringBootApplication
public class MybatisApp {
	public static void main(String[] args) {
		Application.run(MybatisApp.class, args);

		// 打印所有的SQL
		printSqls();

		// 插入数据
		insert();

		// 批量插入
		batchInsert();

		// 更新数据
		update();

		// 删除
		delete();

		// 查询
		queryByCondition();

		// 查询
		queryByConditionSata();

		// 存在
		exists();

		// 锁
		lock();

		// 选择性更新
		updateSelective();

		// 选择性删除
		deleteSelective();

		// 选择性查询
		getSelective();

		// 查询结果
		queryBySelective();

		// 唯一查找
		getUnique();

		// 最强更新
		updative();

		// 清除数据
		clearSelective();

		// 合并
		merge();

		// 是否存在
		existsByCondition();

		// 选择插入
		insertive();
	}

	public static void printSqls() {
		SqlSessionFactory factory = App.getBean(SqlSessionFactory.class);
		Configuration configuration = factory.getConfiguration();
		Collection<String> sqls = configuration.getMappedStatementNames();
		Fmt.out.println("======= 1. 打印所有的SQL =======");
		sqls.stream().forEach(sql -> {
			Fmt.out.println(sql);
		});
	}

	public static void insert() {
		Fmt.out.println("======= 2. 测试插入 =======");
		Test.of().setName("one").setUniqueKey1("1").setUniqueKey2(UUID.randomUUID().toString()).setQuantity(1)
				.setBeginTime(LocalTime.now()).setBeginTime2(LocalTime.now()).insert();
	}

	public static void batchInsert() {
		Fmt.out.println("======= 3. 测试批量插入 =======");
		Test one = Test.of().setName("one").setUniqueKey1("1").setUniqueKey2(UUID.randomUUID().toString())
				.setQuantity(1);
		Test tow = Test.of().setName("tow").setUniqueKey1("2").setUniqueKey2(UUID.randomUUID().toString())
				.setQuantity(1);
		Test three = Test.of().setName("three").setUniqueKey1("3").setUniqueKey2(UUID.randomUUID().toString())
				.setQuantity(1);
		int result = Test.of().addBatch(one).addBatch(tow).addBatch(three).insert().updateOrInsertResult();
		Fmt.out.println("批量插入数据量:" + result);
	}

	public static void update() {
		Fmt.out.println("======= 4. 测试更新 =======");
		Test one = Test.of().setName("one").setUniqueKey1("1").setUniqueKey2(UUID.randomUUID().toString())
				.setQuantity(1).insert();
		Test update = Test.of().setId(one.getId()).get();
		int result = update.setName("one plus").update().updateOrInsertResult();
		Fmt.out.println("更新结果:" + (result == 1 ? "成功" : "失败"));
	}

	public static void delete() {
		Fmt.out.println("======= 5. 测试删除 =======");
		Test one = Test.of().setName("one").setUniqueKey1("1").setUniqueKey2(UUID.randomUUID().toString())
				.setQuantity(1).insert();
		int result = Test.of().setId(one.getId()).delete();
		Fmt.out.println("删除结果:" + (result == 1 ? "成功" : "失败"));
	}

	public static void queryByCondition() {
		Fmt.out.println("======= 6. 测试查询 =======");
		List<Test> tests = Test.of().andEqualTo("NAME", "one").query();
		Fmt.out.println("查询结果:" + (tests.size()));
	}

	public static void queryByConditionSata() {
		Fmt.out.println("======= 7. 测试查询 =======");
		int result = Test.of().andEqualTo("NAME", "one").andIn("ID", Lists.newArrayList(1, 2)).count();
		Fmt.out.println("查询结果:" + result);
	}

	public static void exists() {
		Fmt.out.println("======= 8. 测试存在 =======");
		Test one = Test.of().setName("one").setUniqueKey1("1").setUniqueKey2(UUID.randomUUID().toString())
				.setQuantity(1).insert();
		boolean result = Test.of().setId(one.getId()).exists();
		Fmt.out.println("数据存在:" + result);
		result = Test.of().exists();
		Fmt.out.println("数据不存在:" + result);
	}

	public static void lock() {
		Fmt.out.println("======= 9. 查询锁 =======");
		Test one = Test.of().setName("one").setUniqueKey1("1").setUniqueKey2(UUID.randomUUID().toString())
				.setQuantity(1).insert();
		Test locked = Test.of().setId(one.getId()).lock();
		Fmt.out.println("锁成功:" + (locked != null));
	}

	public static void updateSelective() {
		Fmt.out.println("======= 10. 选择性更新 =======");
		Test one = Test.of().setName("one").setUniqueKey1("1").setUniqueKey2(UUID.randomUUID().toString())
				.setQuantity(1).insert();
		Test update = Test.of().select(Test.Version).setId(one.getId()).get();
		int result = Test.of().setName("one plus").setVersion(update.getVersion()).setId(one.getId()).updateSelective();
		Fmt.out.println("更新结果:" + (result == 1 ? "成功" : "失败"));
	}

	public static void deleteSelective() {
		Fmt.out.println("======= 11. 选择性删除 =======");
		Test one = Test.of().setName("one").setUniqueKey1("1").setUniqueKey2(UUID.randomUUID().toString())
				.setQuantity(1).insert();
		int result = Test.of().setId(one.getId()).deleteSelective();
		Fmt.out.println("删除结果:" + (result == 1 ? "成功" : "失败"));
	}

	public static void getSelective() {
		Fmt.out.println("======= 12. 选择性查找 =======");
		Test one = Test.of().setName("one").setUniqueKey1("1").setUniqueKey2(UUID.randomUUID().toString())
				.setQuantity(1).insert();
		Test get = Test.of().select(Test.Name).andEqualTo(Test.Id, one.getId()).get();
		Fmt.out.println("查找结果:" + (get != null));
	}

	public static void queryBySelective() {
		Fmt.out.println("======= 13. 选择性查询 =======");
		List<Test> gets = Test.of().select(Test.Name).andEqualTo(Test.Name, "tow").query();
		Fmt.out.println("查询结果:" + (gets.size()));
	}

	public static void getUnique() {
		Fmt.out.println("======= 14. 唯一查找 =======");
		Test.of().setName("one").setUniqueKey1("1").setUniqueKey2("1").setQuantity(1).insert();
		Test get = Test.of().setUniqueKey1("1").setUniqueKey2("1").get();
		Fmt.out.println("查询结果:" + (get != null));
	}

	public static void updative() {
		Fmt.out.println("======= 15. 最强更新 =======");
		Test one = Test.of().setName("one").setUniqueKey1("1").setUniqueKey2(UUID.randomUUID().toString())
				.setQuantity(1).insert();
		Test update = Test.of().select(Test.Version).setId(one.getId()).get();
		int result = Test.of().update(Test.Name, "one plus +").clear(Test.Quantity).andEqualTo(Test.Id, one.getId())
				.andEqualTo(Test.Version, update.getVersion()).updative();
		Fmt.out.println("修改结果:" + result);
	}

	public static void clearSelective() {
		Fmt.out.println("======= 16. 清空选择列 =======");
//		Test one = Test.of().setName("one").setUniqueKey1("16").setUniqueKey2(UUID.randomUUID().toString())
//				.setQuantity(1).insert();
//		Test.of().clear(Test.Name).setId(one.getId()).clearSelective();
	}

	public static void merge() {
		Fmt.out.println("======= 17. 合并 =======");
		Test one = Test.of().setName("one").setUniqueKey1("17").setUniqueKey2("17").setQuantity(1).insert();
		Test.of().setUniqueKey1("17").setUniqueKey2("17").setName("one plus").merge();
		Test update = Test.of().setId(one.getId()).get();
		Fmt.out.println("修改结果:" + "one plus".equals(update.getName()));
	}

	public static void existsByCondition() {
		Fmt.out.println("======= 18. 查询数据是否存在 =======");
		Test.of().setName("one").setUniqueKey1("18").setUniqueKey2(UUID.randomUUID().toString()).setQuantity(1)
				.insert();
		boolean result = Test.of().andEqualTo(Test.UniqueKey1, "18").exists();
		Fmt.out.println("查询结果:" + result);
	}

	public static void insertive() {
		Fmt.out.println("======= 19. 测试选择插入 =======");
		Test.of().setName("one").setUniqueKey1("19").setUniqueKey2("19").setQuantity(1).insertive();
		Test two = Test.of().setName("one - 2").setUniqueKey1("19").setUniqueKey2("19").setQuantity(1).insertive(true);
		Fmt.out.println("重复插入结果:" + two.updateOrInsertResult());
	}
}